/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * DisplayMatchedImagesPanel.java
 *
 * Created on Aug 8, 2010, 12:55:31 PM
 */

package tp_imag.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.hibernate.Transaction;
import org.hibernate.Session;
import tp_imag.exception.NoSolutionException;
import tp_imag.gui.components.JImagePanel;
import tp_imag.model.SSSelement;
import tp_imag.service.NewHibernateUtil;
import tp_imag.service.ServiceFactory;
import tp_imag.service.impl.CoordenadaTransformada;

/**
 *
 * @author LRinaudo
 */
public class DisplayMatchedImagesPanel extends javax.swing.JPanel {
    private ArrayList<Integer> solutionsIds = new ArrayList<Integer>();
    private ArrayList<SSSelement> solutions = new ArrayList<SSSelement>();
    private String quantityOfMoreSimilar;
    private String quantityOfSimilar;
    private String quantityOfDifferent;
    private String quantityOfMoreDifferent;
    private Logger logger = Logger.getLogger(DisplayMatchedImagesPanel.class);
    private ArrayList<JPanel> panels = new ArrayList<JPanel>();
    private PanelSoluciones moreSimilar = new PanelSoluciones();
    private PanelSoluciones similar = new PanelSoluciones();
    private PanelSoluciones different = new PanelSoluciones();
    private PanelSoluciones moreDifferent = new PanelSoluciones();
    Iterator iSoluciones;


    /** Creates new form DisplayMatchedImagesPanel */
    public DisplayMatchedImagesPanel() {
        initComponents();
        addMoreComponentes();

    }

    private void addMoreComponentes(){
        this.different.setVisible(true);
        this.similar.setVisible(true);
        this.moreDifferent.setVisible(true);
        this.moreSimilar.setVisible(true);

        this.jPanel2.setLayout(new BorderLayout());
        this.jPanel3.setLayout(new BorderLayout());
        this.jPanel4.setLayout(new BorderLayout());
        this.jPanel1.setLayout(new BorderLayout());
        
        this.jPanel1.add(this.moreSimilar);
        this.jPanel2.add(this.similar);
        this.jPanel3.add(this.different);
        this.jPanel4.add(this.moreDifferent);
    }

    public void updateDisplayMatchedImagesPanel (Vector<CoordenadaTransformada> vt){
        showImages(vt);
        packFrame();
    }

    public void showImages(Vector<CoordenadaTransformada> vt){
        try {
            getImagesMatched(vt);
            setValues();
            //crear la cantidad de paneles que pidan para mas similares y cargarlos con las primeras imagenes del vector soluciones
            this.iSoluciones = this.solutions.iterator();
            int left = addMoreSimilarImages();
            if(left > 0){
                // crear la cantidad de paneles que pidan para similares y cargarlos con las siguientes imagenes del vector soluciones
                left = addImages(left, ((JPanel)similar), this.quantityOfSimilar);
                if (left > 0){
                    // crear la cantidad de paneles que pidan para diferentes y cargarlos con las siguientes imagenes del vector soluciones
                    left = addImages(left, ((JPanel)different), this.quantityOfDifferent);
                    if (left > 0) {
                        // crear la cantidad de paneles que pidan para mas diferentes y cargarlos con las siguientes imagenes del vector soluciones
                        addImages(left, ((JPanel)moreDifferent), this.quantityOfMoreDifferent);
                    }
                }
            }

        } catch (NoSolutionException e){
            //mostrar imagenes que esten en el indice
        }

    }

    private int addMoreSimilarImages(){
        int left = this.solutions.size();
        int indice = 0;
        int quantity = Integer.parseInt(this.quantityOfMoreSimilar);
        
        SSSelement element;
        while ( left > 0 && quantity > 0){
            element = (SSSelement) this.iSoluciones.next();
            BufferedImage image = ServiceFactory.getInstance().getImageProcessorService().openImage(element.getPathOriginal());
            //JImagePanel imagePanel = new JImagePanel();


            int h = image.getHeight();
            int w = image.getWidth();

            JPanel panel = ((JPanel)moreSimilar.getComponent(indice));


            panel.setSize(w, h);
           
            JImagePanel imagePanel = new JImagePanel(image, 0, 0, panel.getSize());

            //imagePanel.setBufferedImage(image);

            panel.setLayout(new BorderLayout());
            imagePanel.setVisible(true);

            panel.add(imagePanel);
            --left;
            --quantity;
            indice++;

        }

        //packFrame();
        return left;
    }

    public void packFrame() {
        Component comp = this;
        while (!(comp instanceof JFrame)) {
            comp = comp.getParent();
        }
        ((JFrame) comp).repaint();
        ((JFrame) comp).validate();
    }

    private int addImages(int leftSolutions, javax.swing.JPanel jpanel, String quantityOfImages){
        int quantity = Integer.parseInt(quantityOfImages);
        
        SSSelement element;
        int indice =0;
        while ( leftSolutions > 0 && quantity > 0){
            element = (SSSelement) this.iSoluciones.next();
            BufferedImage image = ServiceFactory.getInstance().getImageProcessorService().openImage(element.getPathOriginal());

            int h = image.getHeight();
            int w = image.getWidth();
            
            JPanel panel = (JPanel) jpanel.getComponent(indice);
            panel.setSize(w, h);

            JImagePanel imagePanel = new JImagePanel(image, 0, 0, panel.getSize());

            panel.setLayout(new BorderLayout());
            imagePanel.setVisible(true);

            panel.add(imagePanel);

            --leftSolutions;
            --quantity;
            ++indice;
        }
        return leftSolutions;
    }

    private void setValues(){
         Properties properties = new Properties();
         try{
            properties.load(new FileInputStream("DisplayMatchedImagesPanel.properties"));
            this.quantityOfMoreSimilar = properties.getProperty("cantidad.imagenes.mas.similares");
            this.quantityOfSimilar = properties.getProperty("cantidad.imagenes.similares");
            this.quantityOfDifferent = properties.getProperty("cantidad.imagenes.diferentes");
            this.quantityOfMoreDifferent = properties.getProperty("cantidad.imagenes.mas.diferentes");
         } catch(IOException e){
             logger.error("Error al leer el archivo de definición de propiedades");
         }
    }

    private void getImagesMatched(Vector<CoordenadaTransformada> vt) throws NoSolutionException {
       double[] vm=ServiceFactory.getInstance().getMetricSpaceIndexService().CalcularModulo(vt);
       Integer sol;
       ServiceFactory.getInstance().getMetricSpaceIndexService().rangeSearch2(vm, (byte)5, this.solutionsIds);

        if (this.solutionsIds != null && !this.solutionsIds.isEmpty()){
             try {
                   Session session = NewHibernateUtil.getSessionFactory().getCurrentSession();
                   Transaction tx = session.beginTransaction();

                   String parametros="";
                   for (int i = 0; i < this.solutionsIds.size(); i++){
                        parametros+=","+String.valueOf(this.solutionsIds.get(i));
                   }
                   parametros = parametros.replaceFirst(",", "");
                   List elementosGuardados = session.createQuery("select e from SSSelement as e where id in (" + parametros + ") ").list();
                   for (Iterator iter = elementosGuardados.iterator(); iter.hasNext();) {
                         SSSelement sssElement = (SSSelement) iter.next();
                         solutions.add(sssElement);
                         System.out.println(" ID: " + sssElement.getId()+" Path: "+ sssElement.getPathOriginal());
                   }
                   
                   tx.commit();
               } catch (RuntimeException e) {
                   logger.error("Error cuando se estaba recorriendo la lista con las soluciones");
               }
        } else{




           logger.error("La lista de soluciones está vacía");
           throw new NoSolutionException("No se han encontrado coincidencias.");
        }
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jPanel4 = new javax.swing.JPanel();

        setLayout(new java.awt.GridLayout(4, 1));

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Imagenes mas similares"));
        jPanel1.setName("jPanel1"); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 551, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 92, Short.MAX_VALUE)
        );

        add(jPanel1);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Imagenes similares"));
        jPanel2.setName("jPanel2"); // NOI18N

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 551, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 92, Short.MAX_VALUE)
        );

        add(jPanel2);

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Imagenes diferentes"));
        jPanel3.setName("jPanel3"); // NOI18N

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 551, Short.MAX_VALUE)
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 92, Short.MAX_VALUE)
        );

        add(jPanel3);

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Imagenes mas diferentes"));
        jPanel4.setName("jPanel4"); // NOI18N

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 551, Short.MAX_VALUE)
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 92, Short.MAX_VALUE)
        );

        add(jPanel4);
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    // End of variables declaration//GEN-END:variables

}
